/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gclient;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*
 *
 * @author sajin
 */
public class FileTools {

	public FileTools() {
	}
	public static int nChunks(String fileName, int chunkSizeInBytes) {
		File inFile = null;

		try {
			inFile = new File(fileName);

			int nChunk = (int) inFile.length() / chunkSizeInBytes;
			if ( (  inFile.length() - ( nChunk * chunkSizeInBytes)  ) > 0 )
				nChunk += 1;
			
			return nChunk;
		} catch (Exception ex) {
			System.out.println("Error Occured :" + ex.getMessage());
		}  

		return 0; 
	}


	public static byte[] getChunk(String fileName, int chunkSizeInBytes, int chunkNumber) {
		RandomAccessFile inFile = null;

		try {
			inFile = new RandomAccessFile(fileName, "r");

			// Check if there is something in K th chunk.
			if (inFile.length() <= ((chunkNumber - 1) * chunkSizeInBytes)) {
				return null;
			} else {
				inFile.skipBytes((chunkNumber - 1) * chunkSizeInBytes);
				byte[] chunk = new byte[chunkSizeInBytes];

				inFile.read(chunk, 0, chunkSizeInBytes);

				return chunk;
			}
		} catch (Exception ex) {
			System.out.println("Error Occured :" + ex.getMessage());
		} finally {
			try {
				inFile.close();
			} catch( Exception ex ) {
				System.out.println ( " Error Occured " + ex.getMessage() );
			}
		}
		return null;
	}

	public static void joinChunkToFile(String fileName, int chunkSizeInBytes, int chunkNumber, byte[] chunk, int chunkLength) {
		RandomAccessFile inFile = null ;
		try {
			inFile = new RandomAccessFile(fileName, "rwd");


			inFile.skipBytes((chunkNumber - 1) * chunkSizeInBytes);
			inFile.write(chunk, 0,chunkLength);
			
		} catch (Exception ex) {
			System.out.println("Error Occured :" + ex.getMessage());
		} finally {
			try {
				inFile.close();
			} catch( Exception ex ) {
				System.out.println ( " Error Occured " + ex.getMessage() );
			}
		}
	}

	/***
	 *
	 * @param Message Galaxia uses a message format for the chunk where
	 *			      each chunk of bytes is appended with the sha-1 of
	 *			      the file name.
	 * @return Message without sha-1 of file-name
	 */
	public static byte[] extractChunkFromMessage(byte[] Message) {
		// The sha-1 sum is always 20 bytes ( 160 bits ).
		// So extract the sha-1 sum and return the rest.
		byte[] chunk = new byte[Message.length - 20];

		System.arraycopy( Message, 20 , chunk, 0 , Message.length - 20 );

		return chunk;
	}

	/***
	 * 
	 * @param Message Galaxia uses a message format for the chunk where
	 *			      each chunk of bytes is appended with the sha-1 of
	 *			      the file name.
	 * @return sha-1 sum prepended to the chunk.
	 */
	public static byte[] extractSha1SumFromMessage(byte[] Message) {
		// The sha-1 sum is always 20 bytes ( 160 bits )
		// So extract the sha-1 sum and return the rest.
		byte[] sha1Sum = new byte[20];

		System.arraycopy(Message, 0 , sha1Sum , 0 , 20);

		return sha1Sum;
	}

	/**
	 *		Creates the sha-1 digest of files contents.
	 * @param fileName The file whos sha-1 digest is to be found.
	 * @return sha-1 digest of files contents.
	 */
	public static byte[] sha1DigestOfFile(String fileName) throws NoSuchAlgorithmException, IOException {
		File inFile = new File(fileName);
		if ( inFile.exists() ) {
			try {
				FileInputStream inFileStream = new FileInputStream(inFile);
				MessageDigest sha1 = MessageDigest.getInstance("SHA1");

				byte[] fileData = new byte[1024];
				int nBytesRead;

				do {
					nBytesRead =  inFileStream.read(fileData);
					sha1.update(fileData, 0, nBytesRead);
				} while (nBytesRead > 0);

				return sha1.digest();
			} catch (FileNotFoundException ex) {
				System.out.println(" Error Occured : "  + fileName + " NOT FOUND" );
			}

		}

		return null;
	}
}
